package com.xiaoye.digitaltwin.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoye.digitaltwin.common.R;
import com.xiaoye.digitaltwin.easyexcel.listener.StudentListener;
import com.xiaoye.digitaltwin.entity.*;
import com.xiaoye.digitaltwin.entity.dao.BaopoConfirm;
import com.xiaoye.digitaltwin.entity.dao.NeiyaConfirm;
import com.xiaoye.digitaltwin.entity.dao.WaiyaConfirm;
import com.xiaoye.digitaltwin.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;

/**
 * 管理员相关
 * Create by xiaoye on 2023/3/22
 */

@Slf4j
@RestController
@RequestMapping("/administrator")
public class AdministratorController {

    @Autowired
    private AdministratorService administratorService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private IBaopocontrolService baopocontrolService;

    @Autowired
    private IWaiyacontrolService waiyacontrolService;

    @Autowired
    private INeiyacontrolService neiyacontrolService;


    /**
     * 管理员登录
     * @param request
     * @param administrator
     * @return 管理员登陆成功，会将管理员id以变量administratorId存储于session里面
     */
    @PostMapping("/login")
    public R<Administrator> login(@RequestBody Administrator administrator,HttpServletRequest request){

        //对密码进行MD5加密
        String password = administrator.getPassword();
        password = DigestUtils.md5DigestAsHex(password.getBytes());


        //根据username查询数据库
        LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper<>();
        System.out.println(administrator.getUsername());
        queryWrapper.eq(Administrator::getUsername,administrator.getUsername());
        Administrator admin = administratorService.getOne(queryWrapper);

        //username不存在
        if(admin == null){
            return R.error("用户名不存在，登录失败");
        }

        //密码比对
        if(!admin.getPassword().equals(password)){
            log.info(admin.getPassword());
            log.info(administrator.getPassword());
            return R.error("密码不正确，登录失败");
        }

        //查看该管理员状态  0禁用  1启用
        if(admin.getStatus() == 0){
            return R.error("该账号已禁用");
        }

        //登录成功，将id存入Session中并返回
        request.getSession().setAttribute("administratorId",admin.getId());
        return R.success(admin);
    }


    /**
     * 管理员退出登录
     * @param request
     * @return 清除管理员的session
     */
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        //清除session中当前用户id
        request.getSession().removeAttribute("administratorId");
        return R.success("退出成功");
    }


    /**
     * 新增普通管理员 MybatisPlus自带雪花算法，自动生成id
     * @param admin
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody Administrator admin){
        //设置初始密码为123456
        admin.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        administratorService.save(admin);
        return R.success("新增普通管理员成功");
    }

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){
        log.info("page = {},pageSize = {},name = {}" ,page,pageSize,name);

        //构造分页构造器
        Page pageInfo = new Page(page, pageSize);
        //构造条件构造器
        LambdaQueryWrapper<Administrator> queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件    这里的过滤条件好像没用起到作用啊
        queryWrapper.like(StringUtils.isNotEmpty(name),Administrator::getName,name);

        administratorService.page(pageInfo,queryWrapper);
        return R.success(pageInfo);
    }

    /**
     * 根据id修改普通管理员信息
     * @param admin
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody Administrator admin){
        log.info(admin.toString());
        administratorService.updateById(admin);
        return R.success("信息修改成功");
    }

    /**
     * 通过id查询信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<Administrator> getById(@PathVariable Long id){
        Administrator admin = administratorService.getById(id);
        if (admin != null){
            return R.success(admin);
        }
        return R.error("没有查询到对应信息");
    }

    /**
     *管理员更改密码
     * @param id
     * @param oldPass 旧密码
     * @param newPass 新密码
     * @return
     */
    @PostMapping("/password")
    public R<String> changePass(Long id, String oldPass,String newPass){

        //对oldPass进行加密
        oldPass = DigestUtils.md5DigestAsHex(oldPass.getBytes());

        //根据id查询管理员
        Administrator admin = administratorService.getById(id);

        //id传输出错
        if( admin == null){
            return R.error("改用户不存在");
        }

        //旧密码输入有误
        if(!admin.getPassword().equals(oldPass)){
            return R.error("原密码输入有误");
        }

        //对新密码进行加密
        newPass = DigestUtils.md5DigestAsHex(newPass.getBytes());
        UpdateWrapper<Administrator> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",id);
        updateWrapper.set("password",newPass);
        administratorService.update(updateWrapper);
        return R.success("修改密码成功！");
    }

    /**
     * 批量导入学生信息并存储
     * @param file
     * @return
     */
    @PostMapping("/import")
    public R<String> batchImport( MultipartFile file)  throws IOException {

        try {
            EasyExcel.read(file.getInputStream(), Student.class,new StudentListener(studentService)).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
            return R.error("学生信息批量导入失败");
        }
        return R.success("学生信息批量导入成功");
    }


    //R<List<Student>>

    /**
     * 更新内压实验小组成员
     * @param groupNums
     * @return 默认每次更新5个，这里的参数需要是数字
     */
    @GetMapping("/updateNeiyagroup")
    public R<List<Student>> updateNeiyaGroup(String groupNums){
        String nums = groupNums == null? "5":groupNums;

        //nums = groupNums == null?5:groupNums;
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("neiyaFlag","False").or().isNull("neiyaFlag")
                .orderByAsc("stu_no");
        queryWrapper.last("limit " + nums);
        List<Student> students = studentService.list(queryWrapper);
        return R.success(students);
    }

    /**
     * 更新外压实验小组成员
     * @param groupNums
     * @return
     */
    @GetMapping("/updateWaiyagroup")
    public R<List<Student>> updateWaiyaGroup(String groupNums){
        String nums = groupNums == null? "5":groupNums;

        //nums = groupNums == null?5:groupNums;
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("waiyaFlag","False").or().isNull("waiyaFlag")
                .orderByAsc("stu_no");
        queryWrapper.last("limit " + nums);
        List<Student> students = studentService.list(queryWrapper);
        return R.success(students);
    }

    /**
     * 更新爆破实验小组成员
     * @param groupNums
     * @return
     */
    @GetMapping("/updateBaopogroup")
    public R<List<Student>> updateBaopoGroup(String groupNums){
        String nums = groupNums == null? "5":groupNums;

        //nums = groupNums == null?5:groupNums;
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("baopoFlag","False").or().isNull("baopoFlag")
                .orderByAsc("stu_no");
        queryWrapper.last("limit " + nums);
        List<Student> students = studentService.list(queryWrapper);
        return R.success(students);
    }


    /**
     * 管理员端确认开始爆破实验
     * @param baopoConfirm
     * @return
     */
    @PostMapping("/confirmBaopo")
    public R<String> confireBaopo(@RequestBody BaopoConfirm baopoConfirm){
        List<String> stuNos = baopoConfirm.getStuNos();
        if (stuNos == null || stuNos.isEmpty() || stuNos.get(0) == ""){
            return R.error("学号列表为空");
        }
        //现在就说明stuNos不为空，长度也不为0
        int stuNums = stuNos.size();

        //更改学生实验状态
        for (String stuNo : stuNos) {
            UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("stu_no",stuNo).set("baopoFlag","On");
            studentService.update(updateWrapper);
        }

        Baopocontrol baopocontrol = baopocontrolService.check(baopoConfirm);
        UpdateWrapper<Baopocontrol> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",1);
        baopocontrolService.update(baopocontrol,updateWrapper);
        return R.success("爆破实验控制端确认成功");
    }


    /**
     * 管理员端确认开始外压实验
     * @param waiyaConfirm
     * @return
     */
    @PostMapping("/confirmWaiya")
    public R<String> confireWaiya(@RequestBody WaiyaConfirm waiyaConfirm){
        List<String> stuNos = waiyaConfirm.getStuNos();
        if (stuNos == null || stuNos.isEmpty()){
            return R.error("学号列表为空");
        }

        //更改学生实验状态
        for (String stuNo : stuNos) {
            UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("stu_no",stuNo).set("waiyaFlag","On");
            studentService.update(updateWrapper);
        }

        Waiyacontrol waiyacontrol = waiyacontrolService.check(waiyaConfirm);
        UpdateWrapper<Waiyacontrol> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",1);
        waiyacontrolService.update(waiyacontrol,updateWrapper);
        return R.success("外压实验控制端确认成功");
    }

    /**
     * 管理员端确认开始内压实验
     * @param neiyaConfirm
     * @return
     */
    @PostMapping("/confirmNeiya")
    public R<String> confireNeiya(@RequestBody NeiyaConfirm neiyaConfirm){
        List<String> stuNos = neiyaConfirm.getStuNos();
        if (stuNos == null || stuNos.isEmpty()){
            return R.error("学号列表为空");
        }

        //更改学生实验状态
        for (String stuNo : stuNos) {
            UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("stu_no",stuNo).set("neiyaFlag","On");
            studentService.update(updateWrapper);
        }

        Neiyacontrol neiyacontrol = neiyacontrolService.check(neiyaConfirm);
        UpdateWrapper<Neiyacontrol> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",1);
        neiyacontrolService.update(neiyacontrol,updateWrapper);
        return R.success("内压实验控制端确认成功");
    }

    /**
     * 管理员端结束内压实验
     * @param stuNos
     * @return
     */
    @PostMapping("/finshNeiyaExp")
    public R<String> finshNeiyaExp(@RequestBody List<String> stuNos){

        if (stuNos == null || stuNos.isEmpty()){
            return R.error("学号列表为空");
        }

        //先确实学生是否正在开始做实验   即标志位是否为On
        for (String stuNo : stuNos) {
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",stuNo);
            Student student = studentService.getOne(queryWrapper);
            if (!"On".equals(student.getNeiyaFlag())){
                return R.error("该批学生存在实验未开始情况，请先点击实验开始，再点击结束实验");
            }

        }

        for (String stuNo : stuNos) {
            UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("stu_no",stuNo).set("neiyaFlag","True");
            studentService.update(updateWrapper);
        }

        return R.success("内压实验控制端成功结束");
    }

    /**
     * 管理员端结束外压实验
     * @param stuNos
     * @return
     */
    @PostMapping("/finshWaiyaExp")
    public R<String> finshWaiyaExp(@RequestBody List<String> stuNos){
        if (stuNos == null || stuNos.isEmpty()){
            return R.error("学号列表为空");
        }

        //先确实学生是否正在开始做实验   即标志位是否为On
        for (String stuNo : stuNos) {
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",stuNo);
            Student student = studentService.getOne(queryWrapper);
            if (!"On".equals(student.getWaiyaFlag())){
                return R.error("该批学生存在实验未开始情况，请先点击实验开始，再点击结束实验");
            }

        }

        for (String stuNo : stuNos) {
            UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("stu_no",stuNo).set("waiyaFlag","True");
            studentService.update(updateWrapper);
        }

        return R.success("外压实验控制端成功结束");
    }

    /**
     * 管理员端结束爆破实验
     * @param stuNos
     * @return
     */
    @PostMapping("/finshBaopoExp")
    public R<String> finshBaopoExp(@RequestBody List<String> stuNos){
        if (stuNos == null || stuNos.isEmpty()){
            return R.error("学号列表为空");
        }

        //先确实学生是否正在开始做实验   即标志位是否为On
        for (String stuNo : stuNos) {
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no",stuNo);
            Student student = studentService.getOne(queryWrapper);
            if (!"On".equals(student.getBaopoFlag())){
                return R.error("该批学生存在实验未开始情况，请先点击实验开始，再点击结束实验");
            }

        }

        for (String stuNo : stuNos) {
            UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("stu_no",stuNo).set("baopoFlag","True");
            studentService.update(updateWrapper);
        }

        return R.success("爆破实验控制端成功结束");
    }
}
